<?php
class ControllerUrlAlias extends Controller {
	var $error = array();

	function index() {
		$response =& $this->locator->get('response');
		$language =& $this->locator->get('language');
		$template =& $this->locator->get('template'); 
		$module   =& $this->locator->get('module');
 
		$language->load('controller/url_alias.php');

		$template->set('title', $language->get('heading_title'));

		$template->set('content', $this->getList());
		
		$template->set($module->fetch());

		$response->set($template->fetch('layout.tpl'));
	}

	function insert() {
		$request  =& $this->locator->get('request');
		$response =& $this->locator->get('response');
		$database =& $this->locator->get('database');
		$url      =& $this->locator->get('url');
		$language =& $this->locator->get('language');
		$template =& $this->locator->get('template');
		$session  =& $this->locator->get('session');
		$module   =& $this->locator->get('module');
		$cache    =& $this->locator->get('cache');

		$language->load('controller/url_alias.php');

		$template->set('title', $language->get('heading_title'));

		if ($request->isPost() && $request->has('query', 'post') && $this->validateForm()) {
			$sql = "insert into url_alias set query = '?', alias = '?'";
			$database->query($database->parse($sql, $request->get('query', 'post'), $request->get('alias', 'post')));

			$cache->delete('url');

			$session->set('message', $language->get('text_message'));
			
			$response->redirect($url->ssl('url_alias'));
		}

		$template->set('content', $this->getForm());

		$template->set($module->fetch());

		$response->set($template->fetch('layout.tpl'));
	}

	function update() {
		$request  =& $this->locator->get('request');
		$response =& $this->locator->get('response');
		$database =& $this->locator->get('database');
		$url      =& $this->locator->get('url');
		$language =& $this->locator->get('language');
		$template =& $this->locator->get('template');
		$session  =& $this->locator->get('session');
		$module   =& $this->locator->get('module');
		$cache    =& $this->locator->get('cache');

		$language->load('controller/url_alias.php');

		$template->set('title', $language->get('heading_title'));

		if ($request->isPost() && $request->has('query', 'post') && $this->validateForm()) {
			$sql = "update url_alias set query = '?', alias = '?' where url_alias_id = '?'";
			$database->query($database->parse($sql, $request->get('query', 'post'), $request->get('alias', 'post'), $request->get('url_alias_id')));

			$cache->delete('url');
			
			$session->set('message', $language->get('text_message'));
			
			$response->redirect($url->ssl('url_alias'));
		}

		$template->set('content', $this->getForm());

		$template->set($module->fetch());

		$response->set($template->fetch('layout.tpl'));
	}

	function delete() {
		$request  =& $this->locator->get('request');
		$response =& $this->locator->get('response');
		$database =& $this->locator->get('database');
		$url      =& $this->locator->get('url');
		$language =& $this->locator->get('language');
		$template =& $this->locator->get('template');
		$session  =& $this->locator->get('session');
		$module   =& $this->locator->get('module');
		$cache    =& $this->locator->get('cache');

		$language->load('controller/url_alias.php');

		$template->set('title', $language->get('heading_title'));

		if (($request->get('url_alias_id')) && ($this->validateDelete())) {
			$database->query("delete from url_alias where url_alias_id = '" . (int)$request->get('url_alias_id') . "'");
 
			$cache->delete('url');

			$session->set('message', $language->get('text_message'));
			
			$response->redirect($url->ssl('url_alias'));
		}

		$template->set('content', $this->getList());

		$template->set($module->fetch());

		$response->set($template->fetch('layout.tpl'));
	}

	function getList() {
		$request  =& $this->locator->get('request');
		$database =& $this->locator->get('database');
		$config   =& $this->locator->get('config');
		$url      =& $this->locator->get('url');
		$language =& $this->locator->get('language');
		$session  =& $this->locator->get('session');
		$template =& $this->locator->get('template');

		$cols = array();

		$cols[] = array(
			'name'  => $language->get('column_query'),
			'sort'  => 'query',
			'align' => 'left'
		);

		$cols[] = array(
			'name'  => $language->get('column_alias'),
			'sort'  => 'alias',
			'align' => 'left'
		);

    	$cols[] = array(
      		'name'  => $language->get('column_action'),
      		'align' => 'right'
    	);
		
		if (!$session->get('url_alias.search')) {
			$sql = "select url_alias_id, query, alias from url_alias";
		} else {
			$sql = "select url_alias_id, query, alias from url_alias where query like '?' or alias like '?'";
		}

		$sort = array(
			'query',
			'alias'
		);

		if (in_array($session->get('url_alias.sort'), $sort)) {
			$sql .= " order by " . $session->get('url_alias.sort') . " " . (($session->get('url_alias.order') == 'desc') ? 'desc' : 'asc');
		} else {
			$sql .= " order by query asc";
		}

		$results = $database->getRows($database->splitQuery($database->parse($sql, '%' . $session->get('url_alias.search') . '%','%' . $session->get('url_alias.search') . '%'), $session->get('url_alias.page'), $config->get('config_max_rows')));

		$rows = array();

		foreach ($results as $result) {
			$cell = array();

			$cell[] = array(
				'value' => $result['query'],
				'align' => 'left'
			);

			$cell[] = array(
				'value' => $result['alias'],
				'align' => 'left'
			);
			
			$action = array();
      		
			$action[] = array(
        		'icon' => 'update.png',
				'text' => $language->get('button_update'),
				'href' => $url->ssl('url_alias', 'update', array('url_alias_id' => $result['url_alias_id']))
      		);
						
			$action[] = array(
        		'icon' => 'delete.png',
				'text' => $language->get('button_delete'),
				'href' => $url->ssl('url_alias', 'delete', array('url_alias_id' => $result['url_alias_id']))
      		);

      		$cell[] = array(
        		'action' => $action,
        		'align'  => 'right'
      		);
			
			$rows[] = array('cell' => $cell);
		}

		$view = $this->locator->create('template');

		$view->set('tpl', $template);

		$view->set('heading_title', $language->get('heading_title'));
		$view->set('heading_description', $language->get('heading_description', $url->ssl('url_alias', 'generate')));

		$view->set('text_results', $language->get('text_results', $database->getFrom(), $database->getTo(), $database->getTotal()));

		$view->set('entry_page', $language->get('entry_page'));
		$view->set('entry_search', $language->get('entry_search'));

		
		$view->set('button_insert', $language->get('button_insert'));
		$view->set('button_update', $language->get('button_update'));
		$view->set('button_delete', $language->get('button_delete'));

		$view->set('error', @$this->error['message']);

		$view->set('message', $session->get('message'));
		
		$session->delete('message');
		
		$view->set('action', $url->ssl('url_alias', 'page'));
 
		$view->set('search', $session->get('url_alias.search'));
		$view->set('sort', $session->get('url_alias.sort'));
		$view->set('order', $session->get('url_alias.order'));
		$view->set('page', $session->get('url_alias.page'));

		$view->set('cols', $cols);
		$view->set('rows', $rows);

		$view->set('list', $url->ssl('url_alias'));

		$view->set('insert', $url->ssl('url_alias', 'insert'));

		$page_data = array();

		for ($i = 1; $i <= $database->getPages(); $i++) {
			$page_data[] = array(
				'text'  => $language->get('text_pages', $i, $database->getPages()),
				'value' => $i
			);
		}

		$view->set('pages', $page_data);

		return $view->fetch('content/list.tpl');
	}

	function getForm() {
		$request  =& $this->locator->get('request');
		$database =& $this->locator->get('database');
		$url      =& $this->locator->get('url');
		$language =& $this->locator->get('language');
		$template =& $this->locator->get('template');

		$view = $this->locator->create('template');

		$view->set('tpl', $template);

		$view->set('heading_title', $language->get('heading_title'));
		$view->set('heading_description', $language->get('heading_description', $url->ssl('url_alias', 'generate')));

		$view->set('entry_query', $language->get('entry_query'));
		$view->set('entry_alias', $language->get('entry_alias'));

		$view->set('button_save', $language->get('button_save'));
		$view->set('button_cancel', $language->get('button_cancel'));

		$view->set('tab_general', $language->get('tab_general'));

		$view->set('error', @$this->error['message']);
		$view->set('error_query', @$this->error['query']);

		$view->set('action', $url->ssl('url_alias', $request->get('action'), array('url_alias_id' => $request->get('url_alias_id'))));

		$view->set('cancel', $url->ssl('url_alias'));

		if (($request->get('url_alias_id')) && (!$request->isPost())) {
			$url_alias_info = $database->getRow("select distinct query, alias from url_alias where url_alias_id = '" . (int)$request->get('url_alias_id') . "'");
		}

		if ($request->has('query', 'post')) {
			$view->set('query', $request->get('query', 'post'));
		} else {
			$view->set('query', @$url_alias_info['query']);
		}

		if ($request->has('alias', 'post')) {
			$view->set('alias', $request->get('alias', 'post'));
		} else {
			$view->set('alias', @$url_alias_info['alias']);
		}

		return $view->fetch('content/url_alias.tpl');
	}

	function validateForm() {
		$request  =& $this->locator->get('request');
		$language =& $this->locator->get('language');
		$user     =& $this->locator->get('user');
        $validate =& $this->locator->get('validate');

		if (!$user->hasPermission('modify', 'url_alias')) {
			$this->error['message'] = $language->get('error_permission');
		}

		if (!$validate->strlen($request->get('query', 'post'),1,128)) {
			$this->error['query'] = $language->get('error_query');
		}

		if (!$this->error) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	function validateDelete() {
		$user     =& $this->locator->get('user');
		$language =& $this->locator->get('language');

		if (!$user->hasPermission('modify', 'url_alias')) {
			$this->error['message'] = $language->get('error_permission');
		}

		if (!$this->error) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	function page() {
		$request  =& $this->locator->get('request');
		$response =& $this->locator->get('response');
		$url      =& $this->locator->get('url');
		$session  =& $this->locator->get('session');

		if ($request->has('search', 'post')) {
			$session->set('url_alias.search', $request->gethtml('search', 'post'));
		}

		if (($request->has('page', 'post')) || ($request->has('search', 'post'))) {
			$session->set('url_alias.page', $request->gethtml('page', 'post'));
		}

		if ($request->has('sort', 'post')) {
			$session->set('url_alias.order', (($session->get('url_alias.sort') == $request->gethtml('sort', 'post')) && ($session->get('url_alias.order') == 'asc')) ? 'desc' : 'asc');
		}

		if ($request->has('sort', 'post')) {
			$session->set('url_alias.sort', $request->gethtml('sort', 'post'));
		}

		$response->redirect($url->ssl('url_alias'));
	}
	
	function generate()
    {
        $cache    =& $this->locator->get('cache');
        $database =& $this->locator->get('database');
        $response =& $this->locator->get('response');
        $url      =& $this->locator->get('url');
        $language =& $this->locator->get('language');
        $session  =& $this->locator->get('session');

        $language->load('controller/url_alias.php');
        
        $alias = "";
        //delete all records
        $remove_sql = "delete from url_alias";
        $database->query($remove_sql);

        //insert static information
        $this->_insert_url_alias('controller=home', 'index.html');  //NOT YET LOCALIZED
        
        //insert sitemap XML
        //$this->_insert_url_alias('g_sitemap.php', 'sitemap.xml');  //NOT YET LOCALIZED
        
        //$this->_insert_url_alias('controller=contact', 'contact-us.html');  //NOT YET LOCALIZED
        $this->generate_contact_pages();

        $this->_insert_url_alias('controller=sitemap', 'sitemap.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=search', 'search.html');  //NOT YET LOCALIZED

        //Accounts
        $this->_insert_url_alias('controller=account', 'my-account.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_login', 'login.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_logout', 'logout.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_create', 'create-account.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_success', 'account-created.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_download', 'account-downloads.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_edit', 'edit-account.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_password', 'change-password.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_address', 'address-book.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=account_history', 'order-history.html');  //NOT YET LOCALIZED

        //Checkout
        $this->_insert_url_alias('controller=cart', 'cart.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_shipping', 'checkout-shipping.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_address&action=shipping', 'change-shipping-address.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_payment', 'checkout-payment.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_address&action=payment', 'change-payment-address.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_confirm', 'checkout-confirm.html');  //NOT YET LOCALIZED
        $this->_insert_url_alias('controller=checkout_success', 'checkout-success.html');  //NOT YET LOCALIZED

        //generate information
        $sql = "select information_id, title from information_description";
        $this->_generate_url_alias($sql, 'controller=information&information_id={0}', array('information_id'), array('title'));

        //generate product
        $this->generate_for_products();
        //generate categories and sub-categories
        $this->generate_for_categories();
        //generate products in categories
        $this->generate_for_products_in_categories();

        $cache->delete('url');
        
        $session->set('message', $language->get('text_message'));

        $response->redirect($url->ssl('url_alias'));
    }
	
	private function clean_for_google($value)
    {
        //  Make the value attractive to google.
        $value = trim($value);
        $value = str_replace('.', '', $value);
        $value = str_replace(',', '', $value);
        $value = str_replace(';', '', $value);
        $value = str_replace(':', '', $value);
        $value = str_replace(';', '', $value);
        $value = str_replace('\'', '', $value);
        $value = str_replace('"', '', $value);
        $value = str_replace('%', '', $value);
        $value = str_replace('!', '', $value);
        $value = str_replace('$', '', $value);
        $value = str_replace('&amp', 'and', $value);
        $value = str_replace('&', 'and', $value);
        $value = str_replace('/', '', $value);
        $value = str_replace('(', '', $value);
        $value = str_replace(')', '', $value);
        $value = str_replace('=', '', $value);
        $value = str_replace('?', '', $value);
        $value = str_replace('^', '', $value);
        $value = str_replace('@', '', $value);
        $value = str_replace('#', '', $value);
        $value = str_replace('*', '', $value);
        $value = str_replace(' ', '-', $value);
        $value = $this->_removeaccents($value);
        $value = strtolower($value);

        return $value;
    }

    private function generate_contact_pages()
    {
        $database =& $this->locator->get('database');
        $languages = array();
        $data = array();
        //
        //  this is a bit special because we want the title from the language file for each language
        //  We cannot use the language class as it sets session variables as it loads. Instead, for the moment
        //  just cut out bits of code. I am also dodging the cache.
        //
        $results = $database->getRows("select * from language");
        // pre-load so that we can fall back on english
        foreach ($results as $result)
        {
            $languages[$result['code']] = array(
                'language_id' => $result['language_id'],
                'name'        => $result['name'],
                'code'        => $result['code'],
                'directory'   => $result['directory'],
                'filename'    => $result['filename'],
            );
        }

        foreach ($results as $result)
        {
            $language_id = $result['language_id'];
            $directory = HTTP_CATALOG . '/catalog/language/';  // this is a hack since it relies on the values in config.php
            $filename = 'controller/contact.php';
            $file = $directory . $result['directory'] . '/' . $filename;
            if (file_exists($file))
            {
                $_ = array();
                include($file);
                $data = array_merge($data, $_);
            }
            else
            {
                // fall back to english language files.
                $language_id = $languages['en-gb']['language_id'];
                $file = $directory . $languages['en-gb']['directory'] . '/' . $filename;
                if (file_exists($file))
                {
                    $_ = array();
                    include($file);
                    $data = array_merge($data, $_);
                }
                else
                {
                    // do nothing and give up on having an alias for this one.
                    continue;
                }
            }
            $key = 'heading_title';
            if (isset($data[$key]))
            {
                $this->_insert_url_alias('controller=contact', $this->clean_for_google($data[$key]).'.html', $language_id);
            }
            else
            {
                $this->_insert_url_alias('controller=contact', 'contact-us.html');  //NOT YET LOCALIZED
            }


        }


    }
    private function generate_for_categories()
    {
        //generate product into category
        $sql  = "select ";
        $sql .= "    category.path, ";
        $sql .= "    category_description.language_id ";
        $sql .= "from ";
        $sql .= "    category inner join category_description on category.category_id = category_description.category_id ";

        $database =& $this->locator->get('database');
        $results = $database->getRows($sql);
        $alias= '';
        foreach ($results as $result)
        {
            $alias = '';
            //  Generate the url path from the categories,
            //  making sure we only follow the path using the language of the result.
            $language_id = $result['language_id'];
            $categories = explode('_', $result['path']);
            foreach ($categories as $category_id)
            {
                $sql = "select category_description.name as category_name from category_description where category_id = '?' and language_id = '?'";
                $parsed = $database->parse($sql, $category_id, $language_id);
                $row = $database->getRow($parsed);
                // it is possible but unlikely to not get a result here if a category does not have data for each language.
                $alias .= $this->clean_for_google($row['category_name']);
                $alias .= '/';
            }
            $query_path = 'controller=category&path=' . $result['path'];
            $alias = rtrim($alias, '/');
            $alias .= '.html';

            //insert alias
            $this->_insert_url_alias($query_path, $alias, $language_id);
        }
    }

    private function generate_for_products()
    {
        //generate product
        $sql  = "select ";
        $sql .= "    product_id, ";
        $sql .= "    name as product_name, ";
        $sql .= "    language_id ";
        $sql .= "from ";
        $sql .= "    product_description ";

        $database =& $this->locator->get('database');
        $results = $database->getRows($sql);
        $alias= '';
        foreach ($results as $result)
        {
            $alias = '';
            //  Generate the url path from the categories,
            //  making sure we only follow the path using the language of the result.
            $language_id = $result['language_id'];
            $alias .= $this->clean_for_google($result['product_name']);
            $query_path = 'controller=product&product_id=' . $result['product_id'];
            $alias .= '.html';

            //insert alias
            $this->_insert_url_alias($query_path, $alias, $language_id);
        }
    }

    private function generate_for_products_in_categories()
    {
        //generate product into category
        $sql  = "select ";
        $sql .= "    category.path, ";
        $sql .= "    category_description.language_id, ";
        $sql .= "    product_to_category.product_id ";
        $sql .= "from ";
        $sql .= "    category inner join category_description on category.category_id = category_description.category_id ";
        $sql .= "    inner join product_to_category on product_to_category.category_id = category_description.category_id ";

        $database =& $this->locator->get('database');
        $results = $database->getRows($sql);
        $alias= '';
        foreach ($results as $result)
        {
            $alias = '';
            //  Generate the url path from the categories,
            //  making sure we only follow the path using the language of the result.
            $language_id = $result['language_id'];
            $product_id = $result['product_id'];
            $categories = explode('_', $result['path']);
            foreach ($categories as $category_id)
            {
                $sql = "select category_description.name as category_name from category_description where category_id = '?' and language_id = '?'";
                $parsed = $database->parse($sql, $category_id, $language_id);
                $row = $database->getRow($parsed);
                // it is possible but unlikely to not get a result here if a category does not have data for each language.
                $alias .= $this->clean_for_google($row['category_name']);
                $alias .= '/';
            }
            //
            //  Get the product name in the language of the result.
            //
            $sql = "select product_description.name as product_name from product_description where product_id = '?' and language_id = '?'";
            $parsed = $database->parse($sql, $product_id, $language_id);
            $row = $database->getRow($parsed);
            $query_path = 'controller=product&path=' . $result['path'] . '&product_id=' . $product_id;
            $alias .= $this->clean_for_google($row['product_name']);
            $alias .= '.html';

            //insert alias
            $this->_insert_url_alias($query_path, $alias, $language_id);
        }
    }

    private function _generate_url_alias($select_sql, $query, $query_id_array, $alias_id_array) {
        $database =& $this->locator->get('database');

        $results = $database->getRows($select_sql);

        foreach ($results as $result) {
            //build query path
            $query_path = $query;
            foreach ($query_id_array as $key => $value) {
                $query_path = str_replace('{'.$key.'}', $result[$value], $query_path);
            }

            //build alias
            $alias = "";
            foreach ($alias_id_array as $key => $value) {
                $alias .= $result[$value] . " ";
            }

            $alias = trim($alias);
            $alias = str_replace('.', '', $alias);
            $alias = str_replace(',', '', $alias);
            $alias = str_replace(';', '', $alias);
            $alias = str_replace(':', '', $alias);
            $alias = str_replace(';', '', $alias);
            $alias = str_replace('\'', '', $alias);
            $alias = str_replace('"', '', $alias);
            $alias = str_replace('%', '', $alias);
            $alias = str_replace('!', '', $alias);
            $alias = str_replace('$', '', $alias);
            $alias = str_replace('&amp', 'and', $alias);
            $alias = str_replace('&', 'and', $alias);
            $alias = str_replace('/', '', $alias);
            $alias = str_replace('(', '', $alias);
            $alias = str_replace(')', '', $alias);
            $alias = str_replace('=', '', $alias);
            $alias = str_replace('?', '', $alias);
            $alias = str_replace('^', '', $alias);
            $alias = str_replace('@', '', $alias);
            $alias = str_replace('#', '', $alias);
            $alias = str_replace('*', '', $alias);
            $alias = str_replace(' ', '-', $alias);
            $alias = $alias . '.html';
            $alias = $this->_removeaccents($alias);
            $alias = strtolower($alias);
            
            //insert alias
            $this->_insert_url_alias($query_path, $alias);
        }
    }

	function _check_column_exists($table, $col) {
		$database =& $this->locator->get('database');
		//if ($database->countRows(
		if (mysql_num_rows(@mysql_query(sprintf("SHOW COLUMNS FROM %s LIKE '%s'",$table,$col))) > 0) { return true; }
	}
	
    function _insert_url_alias($query, $alias, $language_id = null)
    {
        $database =& $this->locator->get('database');
		$language =& $this->locator->get('language');
		
		if ($language_id == null) { $language_id = $language->getID(); }
		
		if ($this->_check_column_exists('url_alias', 'language_id')) {
			$insert_sql = "replace into url_alias set query = '?', alias = '?', language_id='?'";
			$database->query($database->parse($insert_sql, $query, $alias, $language_id));
		} else {
			$insert_sql = "replace into url_alias set query = '?', alias = '?'";
			$database->query($database->parse($insert_sql, $query, $alias));
		}
    }


    function _removeaccents($string){
        $string = utf8_decode($string);
        $txt = strtr($string,
            "\xe1\xc1\xe0\xc0\xe2\xc2\xe4\xc4\xe3\xc3\xe5\xc5".
            "\xaa\xe7\xc7\xe9\xc9\xe8\xc8\xea\xca\xeb\xcb\xed".
            "\xcd\xec\xcc\xee\xce\xef\xcf\xf1\xd1\xf3\xd3\xf2".
            "\xd2\xf4\xd4\xf6\xd6\xf5\xd5\x8\xd8\xba\xf0\xfa".
            "\xda\xf9\xd9\xfb\xdb\xfc\xdc\xfd\xdd\xff\xe6\xc6\xdf",
             "aAaAaAaAaAaAacCeEeEeEeEiIiIiIiInNoOoOoOoOoOoOoouUuUuUuUyYyaAs");
        return $txt;
    }	
}
?>
